package com.alibaba.otter.manager.web.resource;


import com.alibaba.otter.manager.biz.dto.CommonSearchDTO;
import com.alibaba.otter.manager.biz.config.channel.ChannelService;
import com.alibaba.otter.manager.biz.statistics.stage.ProcessStatService;
import com.alibaba.otter.manager.web.common.model.SeniorChannel;
import com.alibaba.otter.manager.web.dto.RestResponse;
import com.alibaba.otter.manager.web.mapstruct.ChannelMapper;
import com.alibaba.otter.manager.web.utils.PaginationUtil;
import com.alibaba.otter.shared.common.model.config.channel.Channel;
import com.alibaba.otter.shared.common.model.config.channel.ChannelStatus;
import com.alibaba.otter.shared.common.model.config.pipeline.Pipeline;
import com.mybatisflex.core.paginate.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * 通道配置
 */
@RequestMapping("/api/v1/channel")
@RestController
public class ChannelResource {

    private final ChannelService channelService;

    private final ProcessStatService processStatService;

    private final ChannelMapper channelMapper;

    public ChannelResource(ChannelService channelService, ProcessStatService processStatService, ChannelMapper channelMapper) {
        this.channelService = channelService;
        this.processStatService = processStatService;
        this.channelMapper = channelMapper;
    }


    /**
     * 根据id查找通道信息
     */
    @GetMapping("findOne/{id}")
    public RestResponse<Channel> findOne(@PathVariable("id") Long id){
        return RestResponse.ok(channelService.findById(id));
    }

    /**
     * 根据id查找通道信息
     */
    @GetMapping("find-one-pipelineId/{pipelineId}")
    public RestResponse<Channel> findByPipelineId(@PathVariable("pipelineId") Long id){
        return RestResponse.ok(channelService.findByPipelineId(id));
    }



    /**
     * 获取通道列表
     */
    @GetMapping("list")
    public RestResponse<List<SeniorChannel>> list(CommonSearchDTO searchVo, Pageable pageable){
        Page<Channel> channelPage = channelService.channelPage(searchVo, pageable);
        List<Channel> channels = channelPage.getRecords();
        if (CollectionUtils.isEmpty(channels)){
            return PaginationUtil.unPage(pageable);
        }
        List<SeniorChannel> seniorChannels = new ArrayList<>();
        for (Channel channel : channels) {
            List<Pipeline> pipelines = channel.getPipelines();
            SeniorChannel dto = channelMapper.toDTO(channel);
            for (Pipeline pipeline : pipelines) {
                if (processStatService.listRealtimeProcessStat(channel.getId(), pipeline.getId()).isEmpty()) {
                    dto.setProcessEmpty(true);
                }
            }
            seniorChannels.add(dto);
        }
        Page<SeniorChannel> objectPage = Page.of(pageable.getPageNumber(), pageable.getPageSize(), channelPage.getTotalRow());
        objectPage.setRecords(seniorChannels);
        return PaginationUtil.pageHttpResponse(objectPage);
    }

    /**
     * 添加通道
     */
    @PostMapping("add")
    public RestResponse<Void> add(@RequestBody @Validated Channel node){
        channelService.create(node);
        return RestResponse.ok();
    }


    /**
     * 编辑通道配置
     */
    @PutMapping("edit")
    public RestResponse<Void> edit(@RequestBody @Validated Channel node){
        channelService.modify(node);
        return RestResponse.ok();
    }


    /**
     * 根据id删除通道配置
     */
    @DeleteMapping("delete/{id}")
    public RestResponse<Void> delete(@PathVariable("id") Long id){
        channelService.remove(id);
        return RestResponse.ok();
    }


    @PostMapping("status/{id}/{status}")
    public RestResponse<Void> status(@PathVariable("id") Long id, @PathVariable("status") ChannelStatus status){
        if (status == ChannelStatus.START){
            channelService.startChannel(id);

        } else if (status == ChannelStatus.STOP){
            channelService.stopChannel(id);
        }

        return RestResponse.ok();
    }


    @PostMapping("push")
    public RestResponse<Void> push(@RequestParam("id")Long id){
        channelService.notifyChannel(id);
        return RestResponse.ok();
    }
}
